﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Threading;

using RexToy.Logging;
using RexToy.DesignPattern;

namespace RexToy.Cassandra
{
    sealed class ExhaustedBlockPolicy : DisposableBase, IPoolingPolicy
    {
        private static ILog _log = LogContext.GetLogger<IPoolingPolicy>();

        private SemaphoreSlim _semaphore;
        private int _timeOut;
        public void Initialize(List<DnsEndPoint> hosts, int poolSize, int timeOut)
        {
            _semaphore = new SemaphoreSlim(poolSize, poolSize);
            _timeOut = timeOut;
        }

        protected override void DisposeManagedObject()
        {
            _semaphore.Dispose();
        }

        public void Pick(Cluster.Context ctx)
        {
            bool enter = _semaphore.Wait(_timeOut);
            if (enter)
            {
                _log.Debug("Semaphore entered.");
            }
            else
            {
                _log.Warning("Time out.");
                ctx.Stop = true;
                ctx.Reason = StopReason.TimeOut;
            }
        }

        public void Recycle(Cluster.Context ctx)
        {
            _log.Debug("Semaphore release.");
            _semaphore.Release();
        }

        public int AvailableResource
        {
            get { return _semaphore.CurrentCount; }
        }
    }
}
